package org.miyuki4j.cfgtool;


import org.miyuki4j.cfgtool.exception.TypeParseException;
import org.miyuki4j.cfgtool.type.*;

import java.util.HashMap;
import java.util.Map;

/**
 * @Desc
 * @Author miyuki4j
 * @Date 2025/7/24/星期四 13:52
 * @Version 1.0
 */
public class TypeFactory {

    private static final Map<String, Type> SIMPLE_TYPES = new HashMap<>();

    static {
        registerSimpleType(new BoolType());
        registerSimpleType(new IntType());
        registerSimpleType(new LongType());
        registerSimpleType(new FloatType());
        registerSimpleType(new DoubleType());
        registerSimpleType(new StringType());
        registerSimpleType(new RewardType());
        registerSimpleType(new DateType());
    }


    public static void registerSimpleType(Type.SimpleType type) {
        SIMPLE_TYPES.put(type.name(), type);
    }

    public static Type.SimpleType getSimpleType(String type) {
        return (Type.SimpleType) SIMPLE_TYPES.get(type);
    }

    public static Type getType(String tokenType) {
        Type type = getSimpleType(tokenType);
        if (type != null) {
            return type;
        }
        if (StringUtils.startsWith(tokenType, "list<") && StringUtils.endsWith(tokenType, ">")) {
            type = new ListType();
        } else if (StringUtils.startsWith(tokenType, "list2<") && StringUtils.endsWith(tokenType, ">")) {
            type = new List2Type();
        } else if (StringUtils.startsWith(tokenType, "set<") && StringUtils.endsWith(tokenType, ">")) {
            type = new HashSetType();
        } else if (StringUtils.startsWith(tokenType, "treeset<") && StringUtils.endsWith(tokenType, ">")) {
            type = new TreeSetType();
        } else if (StringUtils.startsWith(tokenType, "map<") && StringUtils.endsWith(tokenType, ">")) {
            type = new HashMapType();
        } else if (StringUtils.startsWith(tokenType, "treemap<") && StringUtils.endsWith(tokenType, ">")) {
            type = new TreeSetType();
        }
        if (type == null) {
            throw new TypeParseException("invalid type: " + tokenType);
        }
        return type;
    }

    /**
     * 类型解析
     *
     * @param field
     * @return
     */
    public static Type parse(TableField field, String type, String delimiters) {
        Type javaType = getType(type);
        try {
            javaType.parse(field, type, delimiters);
        } catch (CfgToolException e) {
            throw e;
        } catch (Exception e) {
            throw new TypeParseException(String.format("类型解析异常，class:%s, type:%s", javaType.getClass().getName(), field.getType()), e);
        }
        return javaType;
    }

    public static Type parse(TableField field) {
        return parse(field, field.getType(), field.getDelimiters());
    }
}
